import pygame
from basic_module import *
from pygame.locals import *
from sys import exit

class Cursor:
    
    def __init__(self):
        self.arrow = ( "xX                      ",
                       "X.X                     ",
                       "X..X                    ",
                       "X...X                   ",
                       "X....X                  ",
                       "X.....X                 ",
                       "X......X                ",
                       "X.......X               ",
                       "X........X              ",
                       "X.........X             ",
                       "X....XXXXXXX            ",
                       "X...X                   ",
                       "X..X                    ",
                       "X.X                     ",
                       "XX                      ",
                       "X                       ",
                       "                        ",
                       "                        ",
                       "                        ",
                       "                        ",
                       "                        ",
                       "                        ",
                       "                        ",
                       "                        ")
        self.CURSOR = []
        
        for line in self.arrow:
            self.CURSOR.append(line.replace('x', 'X'))

        try:
            cursor, mask = pygame.cursors.compile(self.CURSOR, 'X', '.', 'o')
            size = len(self.arrow[0]), len(self.arrow)
            pygame.mouse.set_cursor(size,(0, 0), cursor, mask)
        except pygame.error:
            'PygameError',('Check the initialization of Pygame')
            

class Board:
    
    __rect_size = 53, 53
    __board_size = 530, 530
    __board_top = 38
    __board_left = 38
    
    def __init__(self):
        self.__rectangles = []
        self.__board = {}
                        
        for top in xrange(0, 478, 53):
            for left in xrange(0, 478, 53):
                    self.__rectangles.append(Rect((left + self.__board_left, top + self.__board_top),(self.__rect_size)))
                    
        for rect in self.__rectangles:
            line, row = 9 - ((rect.top - 38)/53), ((rect.left - 38)/53)
            self.__board[(line, row)] = rect

    def __str__(self):
        return 'Board of %d x %d pixels, with top in %dpx and left in %dpx,\
        divided in %d rectangles of %d x %d pixels' % (self.__board_size[0], self.__board_size[1],
                                                       self.__board_top, self.__board_left,
                                                        len(self.__rectangles), self.__rect_size[0],
                                                        self.__rect_size[1])
 
    def get_board(self):
        return self.__board

    def get_rectangles(self):
        return self.__rectangles
               
    def get_rectangle(self, position):
        rectangle = self.__board[position]
        return rectangle
    
    def what_rectangle_of_board(self, a, b):
        print 'The second mouse button pressed', a, b
        if 38 < a < 570 and 38 < b < 570:
            for rect in self.get_rectangles():
                if rect.collidepoint(a,b):
                    return rect
        return False
    
    def what_real_place(self, rect):
       for place, rectangle in self.__board.items():
           if rect == rectangle:
               return place

    def get_size(self):
        return self.__board_size
    
    def get_top(self):
        return self.__board_top
    
    def get_left(self):
        return self.__board_left  

class Count:
    def __init__(self, number, top_left):
        self.top_left = top_left
        self.number = number       
        self.font = pygame.font.Font(None, 20)
        self.text = self.font.render(str(self.number), 1, (255, 255, 255))

class Image:

    def __init__(self, name, top_left, image_size = (0,0)):
        self.name = name
        self.size = image_size
        self.top_left = top_left
        self.image = pygame.image.load('Images\%s' % name).convert()
        self.rect = Rect((self.top_left), self.size)  
 
class Game:

    SCREEN_SIZE = 860, 606
    yellow = 255, 255, 120
    red = 255, 0, 0
    white = 255, 255, 255
    tmp = 0
    buttons = {}
    counters = {}
    pieces = {}

    def __init__(self, caption = 'Pygame Window'):
        pygame.init()
        self.Combat = CombatGame()
        self.font_display = pygame.font.Font(None, 16)
        self.screen = pygame.display.set_mode((860, 606), 0, 32)
        pygame.display.set_caption(caption)
        self.background = pygame.image.load('Images\initial_image.jpg').convert()
        cursor = Cursor()
        self.initial_screen()                           # Is it good call main() here?

    def what_todo(self, a, b):
        bool, rect = self.is_button(a, b)               # Is it a button (buttons or pieces to add to the board)?
        if bool:
            self.what_todo_buttons(a, b)
            return
        bool, rect = self.is_board(a, b)                # Is it on the board?
        if bool:
            if self.is_piece_of_board(a, b)[0]:         # If it's on the board, is it a piece?
                self.change_piece(a, b)                 # How it's a piece, do you wanna change place?
            return

    def what_todo_buttons(self, a, b):
        if bool:
            name = self.what_button(a, b)[1]
            print name
            if name == 'new_game':
                self.second_screen()
            elif name == 'exit':
                exit()
            elif name == 'host_game':
                #gs = GameServer(self)
                #gs.start()
                self.owner = 'host'
                self.populate_third_screen()
            elif name == 'join_game':
                #gc = GameClient(self)
                #gc.start()
                self.owner = 'join'
                self.populate_third_screen()
            elif name == 'ready':
                if len(self.Combat.army) == 0:
                    print 'MASSA'                         # Ok now let's to the last one
                    self.battle_fourth_screen()                 ############### We have to create it
            elif name == 'attack_button':
                pass
            elif name == 'allied_grav':
                self.allied_grav_screen()                ############### We have to create it
            elif name == 'enemy_grav':
                self.enemy_grav_screen()                ############### We have to create it
            elif name == 'retreat':                    ############### We have to create it
                exit()        
            elif name == 'return':                    ############### We have to create it
                self.battle_fourth_screen()# This method have to use the same board of the populate board
                                           # so it cannot change the position of the pieces
            else:
                self.where_populate(name)
        
    def where_populate(self, name):
        x, y = self.second_mouse_press()
        if self.is_board(x, y)[0]:
            rect = self.is_board(x, y)[1]
            x, y = rect.topleft
            line, row = self.board.what_real_place(rect)
            try:
                self.Combat.add_piece(name, line, row)
                self.create_piece(name, (x + 2, y + 2))
                font = Game.counters[name]    
                font.number -=1
                font.text = font.font.render(str(font.number), 1, Game.white)
            except Exception, (message):
                print message
                       
    def walking_populating(self, piece, x, y, a, b):
        line1, row1 = self.what_place_onboard(x,y)
        line2, row2 = self.what_place_onboard(a,b)
        rect = self.board.what_rectangle_of_board(a, b)
        print 'All the rectangles',self.board.get_rectangles(),'\n The rectangle that i pressed', rect
        try:
            self.Combat.change_pieces(line1, row1, line2, row2)
            piece.top_left = rect.left + 2, rect.top + 2
        except Exception, (message):
            print message
            
            
###### WE HAVE A PROBLEM WHEN WE TRAVERSE THE LIST OF OBJECTS, WE ARE RECEIVING THE WRONGS OBJECTS OR NONE,
#BECAUSE HOW WE CHANGED THE ATRIBUTES OF THAT OBJECT IT ISN'T THE SAME ANYMORE########

            
    def what_button(self, a, b):
        rects = []
        for name, button in Game.buttons.items():
            if button.rect.collidepoint(a, b):
                    return button, name
        
    def what_place_onboard(self, a, b):        
        return 9 - ((b - 38)/53), ((a - 38)/53) 
    
    
    def second_mouse_press(self):
        while True:
            for event in pygame.event.get():
                if event.type == MOUSEBUTTONDOWN:
                    x, y = pygame.mouse.get_pos()
                    return x, y
                if event.type == QUIT:
                    exit()       
        return False
        
    def initial_screen(self):
        Game.buttons = {'new_game': Image('new_game.jpg', (303, 342), (255,54)),
                        'exit': Image('exit.jpg', (375, 422), (111, 61))}
        
#######       
        
    def second_screen(self):
        Game.buttons = {'host_game': Image('host_game.jpg', (282, 337), (296, 61)),
                        'join_game': Image('join_game.jpg', (292, 418), (265, 57))}
        
#######

    def populate_third_screen(self):  
        self.board = Board()
        if self.owner == 'host':
            self.letter = 'r'
        elif self.owner == 'join':
            self.letter = 'b'
        letter = self.letter
        
        self.background = pygame.image.load('Images\populating_%s.jpg' % letter).convert()

        Game.buttons = {'ready': Image('ready_%s.jpg'% letter, (732, 37), (93, 28)),
                        'spy': Image('spy_%s.jpg'% letter, (661,500),(49,49)), 
                        'scout': Image('scout_%s.jpg'% letter, (754,500),(49,49)),
                        'miner': Image('miner_%s.jpg'% letter, (661,430),(49,49)),
                        'sergeant': Image('sergeant_%s.jpg'% letter, (754,430),(49,49)),
                        'lieutenant': Image('lieutenant_%s.jpg'% letter, (661,360),(49,49)),
                        'captain': Image('captain_%s.jpg'% letter, (754,360),(49,49)),
                        'major': Image('major_%s.jpg'% letter, (661,290),(49,49)),
                        'colonel': Image('colonel_%s.jpg'% letter, (754,290),(49,49)),
                        'general': Image('general_%s.jpg'% letter, (661,220),(49,49)),
                        'marshal': Image('marshal_%s.jpg'% letter, (754,220),(49,49)),
                        'bomb': Image('bomb_%s.jpg'% letter, (661,150),(49,49)),
                        'flag': Image('flag_%s.jpg'% letter, (754,150),(49,49))}    

          

        Game.counters = {'spy': Count(self.get_count('spy'),(716, 521)),
                        'scout':Count(self.get_count('scout'),(741, 521)),
                        'miner': Count(self.get_count('miner'),(716, 451)),
                        'sergeant':Count(self.get_count('sergeant'),(741, 451)),
                        'lieutenant':Count(self.get_count('lieutenant'),(716, 381)),
                        'captain':Count(self.get_count('captain'),(741, 381)),
                        'major':Count(self.get_count('major'),(716, 311)),
                        'colonel':Count(self.get_count('colonel'),(741, 311)),
                        'general':Count(self.get_count('general'),(716, 241)),
                        'marshal':Count(self.get_count('marshal'),(741, 241)),
                        'bomb':Count(self.get_count('bomb'),(716, 171)),
                        'flag':Count(self.get_count('flag'),(741, 171))}
    
    
    def blit_buttons(self): 
        buttons = Game.buttons.values()
        for button in buttons:
            self.screen.blit(button.image, button.top_left)
    
    def get_count(self, name):
        value = self.Combat.army.count(name)  
        return value
            
    def blit_counter(self):
        for count in Game.counters.values():
            self.screen.blit(count.text, count.top_left)
        
    def create_piece(self, name, top_left):
        size = 49,49
        if self.get_count(name) >= 0:
            Game.pieces[name] = Game.pieces.get(name,[])+[Image('%s_%s.jpg'% (name, self.letter), top_left, size)]
    
    def change_piece(self, x, y):
        piece1 = self.what_piece(x, y)
        a, b = self.second_mouse_press()
        if self.is_piece_of_board(a, b)[0]:
            piece2 = self.what_piece(a, b)
            piece1.top_left, piece2.top_left = piece2.top_left, piece1.top_left
        else:
            self.walking_populating(piece1, x, y, a, b)
    
    def blit_pieces(self):
        for list in Game.pieces.values():
            for piece in list:
                self.screen.blit(piece.image, piece.top_left)
    
    def connection(self):
        if self.owner == 'host': # and the joinner didn't had connected
            Game.buttons['wait_connect'] = Image('wait_connect.jpg', (289, 44))
            #if the joinner had connected
            del(Game.butons['wait_connect'])
            Game.buttons['connected'] = Image('connected.jpg', (416, 416))
 
            
###########      
 
    def battle_fourth_screen(self): # Here we have to pay attention to the fact that the player 
        pass                        # can consult the graveyard and return to the battle,
                                    # so this method cannot be so difficult
    def render_graveyard_counters(self):
        pass
    
    def what_piece(self, a, b):
        for list in Game.pieces.values():
            for piece in list:
                if piece.rect.collidepoint(a, b):
                    return piece
                
    def walking(self, a, b): ##################################################################
        for piece in Game.pieces.values():
            if piece.rect.collidepoint(a,b):
                line, row = self.what_place_onboard(a,b)
        x, y = self.second_mouse_press()
        if self.is_board(x, y) and len(self.Combat.where_move()) != 0:
            self.Combat.move(line, row, x, y)
            piece = self.what_piece(line, row)
            piece.top_left = x, y
    

########### Here we have the tests for each type of piece ########

    def is_board(self, a, b):
        if len(Game.buttons) > 3:
            for rect in self.board.get_rectangles():
                if rect.collidepoint((a,b)):
                 return True, rect
        return False, []
    
    def is_button(self, a, b):
        for button in Game.buttons.values():
            if button.rect.collidepoint(a,b):
                return button.rect.collidepoint((a, b)), button
        return False, []
    
    def is_piece_of_board(self, a, b):
        if len(Game.pieces) != 0:
            for lista in Game.pieces.values():
                for piece in lista:
                    if piece.rect.collidepoint(a, b):
                        return True, piece
        return False, []
        
    
##### These methods now are used only to test, but they could be used #########
            
    def fill_square(self,a, b):
        rect = self.board.what_rectangle_of_board(a, b)
        self.screen.fill(Game.yellow, rect)


    def get_move(self, x, y):
        is_rect, rect = self.is_board(x,y)
        if is_rect and rect != Game.tmp:
            Game.count_pressed += 1
            self.fill_square(rect,'move') #### Here we have to know what there in the rect, to know what kind of will we print
            Game.tmp = rect
            if Game.count_pressed >1:
                Game.count_pressed, Game.tmp = 0, 0
                self.screen.blit(self.background,(0, 0))   # Here we will print what where_to returns

    def main(self):
        self.screen.blit(self.background, (0, 0))  # This will never change
        ## But the buttons and pieces will be blitted here, after the background ###
        while True:
            pygame.event.set_allowed([QUIT, MOUSEBUTTONDOWN, MOUSEBUTTONUP])
            for event in pygame.event.get():
                if event.type == QUIT:
                    exit()
                if event.type == MOUSEBUTTONDOWN:
                    x,y = pygame.mouse.get_pos()
                    self.get_move(x, y)            # These methods will store the diferent actions in all the game
                    self.get_populate()
                    self.get_button_pressed()

        self.screen.display.update()
        
        
game = Game('PyCombat')

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
        if event.type == MOUSEBUTTONDOWN:
            x,y = pygame.mouse.get_pos()
            game.what_todo(x, y)

    game.screen.blit(game.background,(0,0))
    game.blit_buttons()
    game.blit_counter()
    game.blit_pieces()
    pygame.display.update()
   
 
'''TODO:
To create the end screen
To move the rectangles (Its easy, we only have to use: Surface.blit(image, cordinate))'''
import pygame
import sys
import basic_module
from pygame.locals import *

class Cursor:
    
    def __init__(self):
        self.arrow = ( "xX                      ",
                       "X.X                     ",
                       "X..X                    ",
                       "X...X                   ",
                       "X....X                  ",
                       "X.....X                 ",
                       "X......X                ",
                       "X.......X               ",
                       "X........X              ",
                       "X.........X             ",
                       "X......XXXXX            ",
                       "X...X..X                ",
                       "X..XX..X                ",
                       "X.X XX..X               ",
                       "XX   X..X               ",
                       "X     X..X              ",
                       "      X..X              ",
                       "       X..X             ",
                       "       X..X             ",
                       "        XX              ",
                       "                        ",
                       "                        ",
                       "                        ",
                       "                        ")
        self.CURSOR = []
        
        for line in self.arrow:
            self.CURSOR.append(line.replace('x', 'X'))

    def create(self):
        try:
            cursor, mask = pygame.cursors.compile(self.CURSOR, 'X', '.', 'o')
            size = len(self.arrow[0]), len(self.arrow)
            pygame.mouse.set_cursor(size,(0, 0), cursor, mask)
        except pygame.error:
            'PygameError',('Check the initialization of Pygame')
            

class Board:
    
    __rect_size = 53, 53
    __board_size = 530, 530
    __board_top = 38
    __board_left = 38
    
    def __init__(self):
        self.__rectangles = []
        self.__board = {}
                        
        for top in xrange(0, 478, 53):
            for left in xrange(0, 478, 53):
                    self.__rectangles.append(Rect((left + self.__board_left, top + self.__board_top),(self.__rect_size)))
                    
        for rect in self.__rectangles:
            row = rect.left/53
            line = 9 - (rect.top/53)
            self.__board[(line, row)] = rect

    def __str__(self):
        return 'Board of %d x %d pixels, with top in %dpx and left in %dpx,\
 divided in %d rectangles of %d x %d pixels' % (self.__board_size[0], self.__board_size[1],
                                                       self.__board_top, self.__board_left,
                                                        len(self.__rectangles), self.__rect_size[0],
                                                        self.__rect_size[1])
 
    def get_board(self):
        return self.__board

    def get_rectangles(self):
        return self.__board.values()
               
    def get_rectangle(self, position):
        rectangle = self.__board[position]
        return rectangle
    
    def what_place(self, rect):
       for place, rectangle in self.__board.items():
           if rect == rectangle:
               return place

    def get_size(self):
        return self.__board_size
    
    def get_top(self):
        return self.__board_top
    
    def get_left(self):
        return self.__board_left  

class Image:

    def __init__(self, name, top_left, image_size = (0,0)):
        self.size = image_size
        self.image = pygame.image.load(name).convert()
        self.top_left = top_left
        self.rect = Rect((self.top_left), image_size)  
  
class Game:

    SCREEN_SIZE = 860, 606
    yellow = 255, 255, 120
    red = 255, 0, 0
    count_pressed = 0
    tmp = 0
    image = 'initial_image.jpg'
    buttons = {}

    def __init__(self, owner, caption = 'Pygame Window'):
        self.owner = owner
        pygame.init()
        self.image_filename = Game.image                           # Think about put this part in main or...
        self.screen = pygame.display.set_mode(Game.SCREEN_SIZE, 0, 32)
        pygame.display.set_caption(caption)
        self.background = pygame.image.load(Game.image).convert()
        self.initial_screen()        # Is it good call main() here?
       
       
    def initial_screen(self):
        Game.buttons = {'new_game': Image('new_game', (303, 342), (255,54)),
                        'exit': Image('exit.jpg', (376, 342), (110, 53))}
        
        
    def second_screen(self):
        Game.buttons = {'host_game': Image('host_game.jpg', (282, 337), (296, 61)),
                        'join_game': Image('join_game.jpg', (294, 337), (266, 60))}
        

    def populate_third_screen(self):
        #if you hosted = red, if you joined = blue ( SO WE WILL DO A CONCATENATION OF STRING)        
        Game.image = 'populating.jpg'
        self.board = Board()
        if self.owner == 'Red':
            letter = 'r'
        elif self.owner == 'Blue':
            letter = 'b'

        Game.buttons = {'ready': Image('ready_%s.jpg'% letter, (732, 37), (93, 28)),
                        'spy': Image('spy_%s.jpg'% letter, (661,500),(49,49)), 
                        'scout': Image('scout_%s.jpg'% letter, (754,500),(49,49)),
                        'miner': Image('miner_%s.jpg'% letter, (661,430),(49,49)),
                        'sergeant': Image('sergeant_%s.jpg'% letter, (754,430),(49,49)),
                        'lieutenant': Image('lieutenant_%s.jpg'% letter, (661,360),(49,49)),
                        'captain': Image('captain_%s.jpg'% letter, (754,360),(49,49)),
                        'major': Image('major_%s.jpg'% letter, (661,290),(49,49)),
                        'colonel': Image('colonel_%s.jpg'% letter, (754,290),(49,49)),
                        'general': Image('general_%s.jpg'% letter, (661,220),(49,49)),
                        'marshal': Image('marshal_%s.jpg'% letter, (754,220),(49,49)),
                        'bomb': Image('bomb_%s.jpg'% letter, (661,150),(49,49)),
                        'flag': Image('flag_%s.jpg'% letter, (754,150),(49,49))}    

    def blit_buttons(self):  # With this method we can blit all the pieces in your currently Game.buttons
        buttons = Game.buttons.values()
        for button in buttons:
            self.screen.blit(button, button.size)

########### Here we have the tests for each type of piece ########

    def is_board(self, a, b):
        for rect in self.board.get_rectangles():
            if rect.collidepoint((a,b)):
             return rect.collidepoint((a,b)), rect
        return False, []
    
    def is_button(self, a, b):
        for rect in Game.buttons.values():
            if rect.collidepoint(a,b):
                return rect.collidepoint((a, b)), rect
        return False, []
    
    def is_piece(self, rectangle): # This method receives the rectangle from the method "is_button"
        for button, rect in Game.buttons.items():
            if rectangle == rect:
                  return True, button
        return False, []

############### Here we could divide the class, and the other will inherite this ################

    def which_button(self, button):
        if button == 'new_game':
            self.second_screen()
        elif button == 'exit':
            exit()
        elif button == 'host_game':
            # Here we will call the methods of "network module"
            self.populate_third_screen()
        elif button == 'join_game':
            # Here we will wait for the conection ("network module")
            self.populate_third_screen()
        elif button == 'ready':
            # Here er begin to use the "basic_module"
            self.battle_fourth_screen()                 ############### We have to create it
        elif button == 'attack_button':
            pass
            # We call the methods of basic_module"
        elif button == 'allied_grav':
            self.allied_grav_screen()                ############### We have to create it
        elif button == 'enemy_grav':
            self.enemy_grav_screen()                ############### We have to create it
        elif button == 'retreat':                    ############### We have to create it
            exit()        
        elif button == 'return':                    ############### We have to create it
            self.battle_fourth_screen()# This method have to use the same board of the populate board
                                       # so it cannot change the position of the pieces
            
    
##### These methods now are used only to test, but they can be better #########
            
    def fill_square(self, rect, kind):
        if kind == 'move':                      # Here we won't have this strings, we will have the call of the basic_module
            self.screen.fill(Game.yellow, rect)
        elif kind == 'attack':
            self.screen.fill(Game.red, rect)


    def get_move(self, x, y):
        is_rect, rect = self.is_board(x,y)
        if is_rect and rect != Game.tmp:
            Game.count_pressed += 1
            self.fill_square(rect,'move') #### Here we have to know what there in the rect, to know what kind of will we print
            Game.tmp = rect
            if Game.count_pressed >1:
                Game.count_pressed, Game.tmp = 0, 0
                self.screen.blit(self.background,(0, 0))   # Here we will print what where_to returns



    def get_populate(self, x, y):
        is_piece, piece = self.is_piece(x, y)  # When it is POPULATING, this will be the unique method to move the pieces
        pass                                   # We have to create a method to instanciate and store in a map, all the Army 
    
    def get_button_pressed(self):
        pass                        # Here we only have to create the rect, in each place


    def main(self):
        self.screen.blit(self.background, (0, 0))  # This will never change
        ## But the buttons and pieces will be blitted here, after the background ###
        while True:
            pygame.event.set_allowed([QUIT, MOUSEBUTTONDOWN, MOUSEBUTTONUP])
            for event in pygame.event.get():
                if event.type == QUIT:
                    exit()
                if event.type == MOUSEBUTTONDOWN:
                    x,y = pygame.mouse.get_pos()
                    self.get_move(x, y)            # These methods will store the diferent actions in all the game
                    self.get_populate()
                    self.get_button_pressed()

        self.screen.display.update()   

    
game = Game('map_vision.jpg')
game.set_caption('PyCombat')
print game.get_size()
x, y = game.is_board(344, 78)
print x, y

game.fill_square(y,'')
game.get_move(300, 120)
game.get_move(300, 120)
print Game.count_pressed



 
'''TODO:
We have to put all the army in the right place
We have to divide screen in diferent rectangles
We have to create the screen of both graveyards (We had the idea, only put the number of each piece( for in the pieces of the graveyard, and getting theirs names)
To create the normal view of game, and buttons (ATTACK BUTTON, ALLIED AND ENEMY GRAVEYARD, ENTER of CHAT)
To create the end screen
To move the rectangles (Its easy, we only have to use: Surface.blit(image, cordinate))'''